package com.beta.cat.config.clickhouse;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.clickhouse.BalancedClickhouseDriver;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.Resource;
import ru.yandex.clickhouse.BalancedClickhouseDataSource;
import ru.yandex.clickhouse.settings.ClickHouseProperties;

import java.util.List;
import java.util.Properties;

/**
 * <pre>
 * 集成clickhouse的基本操作。注意使用时，要引用clickhouse的jar包。
 * clickhouse默认支持Mybatis方式：只需要配置如下：
 * spring.datasource.clickhouse.basePackage=xxx
 * spring.datasource.clickhouse.mapperLocations=classpath:/yyy/*.xml
 *
 * 根据不同的连接方式，配置对应的详细参数，配置时，前缀为：spring.datasource.clickhouse.defaults，如：
 * # 原生情况下指定连接数
 * spring.datasource.clickhouse.defaults.maxTotal=30
 * spring.datasource.clickhouse.defaults.maxThreads=30
 *
 * # 使用druid时，指定连接数
 * spring.datasource.clickhouse.defaults.druid.maxActive
 * </pre>
 */
@Configuration
@ConditionalOnProperty(name = "com.beta.clickhouse.enable", havingValue = "true", matchIfMissing = false)
@EnableConfigurationProperties(ClickHouseConfiguration.ClickhouseDatasourceProperties.class)
@Import(ClickhouseImportRegistrar.class)
public class ClickHouseConfiguration {
    public static final String prefix = "spring.datasource.clickhouse";

    @ConfigurationProperties(prefix = prefix)
    @Data
    public static class ClickhouseDatasourceProperties {
        public ClickhouseDatasourceProperties() {
            super();
        }

        private String url;
        private String username;
        private String password;
        private Properties defaults;

        private String basePackage;
        private List<Resource> mapperLocations;
    }

    /**
     * 如果有Druid连接池，则优先使用它
     *
     * @param config
     * @return
     */
    @Bean
    @ConditionalOnClass(name = "com.alibaba.druid.support.clickhouse.BalancedClickhouseDriver")
    @Order(1)
    public ClickhouseService clickhouseServiceInDruid(ClickhouseDatasourceProperties config) {
        if (StringUtils.isBlank(config.getUrl())) {
            throw new IllegalArgumentException("缺少clickhouse的配置");
        }
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(BalancedClickhouseDriver.class.getName());
        dataSource.setUrl(config.getUrl());
        dataSource.setUsername(config.getUsername());
        dataSource.setPassword(config.getPassword());
        dataSource.setConnectProperties(config.getDefaults());
        return new ClickhouseService(dataSource);
    }

    @Bean
    @ConditionalOnMissingBean
    @Order(10)
    public ClickhouseService clickhouseService(ClickhouseDatasourceProperties config) {
        if (StringUtils.isBlank(config.getUrl())) {
            throw new IllegalArgumentException("缺少clickhouse的配置");
        }
        Properties defaults = config.getDefaults();
        if (defaults == null) {
            defaults = new Properties();
        }
        ClickHouseProperties properties = new ClickHouseProperties(defaults);
        properties.setUser(config.getUsername());
        properties.setPassword(config.getPassword());

        BalancedClickhouseDataSource dataSource = new BalancedClickhouseDataSource(config.getUrl(), properties);

        return new ClickhouseService(dataSource);
    }

}
